package com.hele.sts.filter;

import com.hele.sts.filter.waf.request.WafRequestWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Created by xuning on 2016/9/1 0001.
 * User:xuning
 *
 * @date ${.now?string["yyyy-MM-dd HH:mm:ss"]} \n
 */
public class SecurityFilter implements Filter {

    private static final Logger logger = LoggerFactory.getLogger(SecurityFilter.class);

    private static String OVER_URL = null;//非过滤地址

    private static boolean FILTER_XSS = true;//开启XSS脚本过滤

    private static boolean FILTER_SQL = true;//开启SQL注入过滤

    @Override
    public void init(FilterConfig config) throws ServletException {
        //读取Web.xml配置地址
        OVER_URL = config.getInitParameter("over.url");

        FILTER_XSS = getParamConfig(config.getInitParameter("filter_xss"));
        FILTER_SQL = getParamConfig(config.getInitParameter("filter_sql_injection"));
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        //chain.doFilter(new XSSRequestWrapper1((HttpServletRequest) request), response);
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        String httpMethod = req.getMethod();
        if (!"GET".equals(httpMethod) && !"POST".equals(httpMethod) && !"HEAD".equals(httpMethod) ) {
            res.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET POST or HEAD");
            return;
        }
        String host = req.getRemoteHost();
        StringBuffer url = req.getRequestURL();
//        String url1 = null;
//        if(url !=null && url.indexOf("nbzwy")>0){
//        	url1 = url.substring(0,url.indexOf("nbzwy")-1);
//        }
        String referer=req.getHeader( "Referer" );
//                                                                                                                                 logger.info("url:"+url1);
        logger.info("host:"+host);
//        logger.info("referer:"+referer);
//        if((!"127.0.0.1".equals(host)) && (!"localhost".equals(host)) && (!"0:0:0:0:0:0:0:1".equals(host))){
//        	if ((referer!= null ) && (!(referer.contains(host)))){
//                request.getRequestDispatcher( "/errorProcessor" ).forward(request,response);
//                return;
//            }
//        }
        if(url.toString().endsWith(".cab")){
            chain.doFilter(request, response);
            return;
        }

        boolean isOver = inContainURL(req, OVER_URL);

        /** 非拦截URL、直接通过. */
        if ( !isOver ) {
            try {
                //Request请求XSS过滤
                chain.doFilter(new WafRequestWrapper(req, FILTER_XSS, FILTER_SQL), response);
            } catch ( Exception e ) {
                logger.error(" WafFilter exception , requestURL: " + req.getRequestURL());
            }
        }
        else {
             chain.doFilter(request, response);
        }

    }

    @Override
    public void destroy() {

    }

    /**
     * @Description 获取参数配置
     * @param value
     *            配置参数
     * @return 未配置返回 True
     */
    private boolean getParamConfig( String value ) {
        if ( value == null || "".equals(value.trim()) ) {
            //未配置默认 True
            return true;
        }
        return new Boolean(value);
    }

    /**
     *
     * <p>
     * getRequestURL是否包含在URL之内
     * </p>
     *
     * @param request
     * @param url
     *            参数为以';'分割的URL字符串
     * @return
     */
    public boolean inContainURL(HttpServletRequest request, String url) {
        boolean result = false;
        if (url != null && !"".equals(url.trim())) {
            String[] urlArr = url.split(";");
            StringBuffer reqUrl = new StringBuffer(request.getRequestURL());
            for (int i = 0; i < urlArr.length; i++) {
                if (reqUrl.indexOf(urlArr[i]) > 1) {
                    result = true;
                    break;
                }
            }
        }
        return result;
    }
}
